package org.gdstash.trade;

import org.gdstash.db.DBItem;
import org.gdstash.db.DBStashItem;
import org.gdstash.item.GDItem;
import org.gdstash.util.GDConstants;
import org.gdstash.util.GDMsgFormatter;

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.List;
import java.util.*;

public class GDTradeList {
    private static int getRarityInt(final String rarity) {
        int val = 0;
        if (rarity.equals("Epic")) {
            val = 1;
        }
        if (rarity.equals("Legendary")) {
            val = 2;
        }
        return val;
    }

    private static int getItemClassInt(final String itemClass) {
        if (itemClass == null) {
            return 0;
        }
        int val = 0;
        if (itemClass.equals("ArmorProtective_Head")) {
            val = 1;
        }
        if (itemClass.equals("ArmorProtective_Shoulders")) {
            val = 2;
        }
        if (itemClass.equals("ArmorProtective_Chest")) {
            val = 3;
        }
        if (itemClass.equals("ArmorProtective_Hands")) {
            val = 4;
        }
        if (itemClass.equals("ArmorProtective_Legs")) {
            val = 5;
        }
        if (itemClass.equals("ArmorProtective_Feet")) {
            val = 6;
        }
        if (itemClass.equals("ArmorProtective_Waist")) {
            val = 11;
        }
        if (itemClass.equals("ArmorJewelry_Amulet")) {
            val = 12;
        }
        if (itemClass.equals("ArmorJewelry_Medal")) {
            val = 13;
        }
        if (itemClass.equals("ArmorJewelry_Ring")) {
            val = 14;
        }
        if (itemClass.equals("WeaponMelee_Axe")) {
            val = 21;
        }
        if (itemClass.equals("WeaponMelee_Dagger")) {
            val = 22;
        }
        if (itemClass.equals("WeaponMelee_Mace")) {
            val = 23;
        }
        if (itemClass.equals("WeaponMelee_Scepter")) {
            val = 24;
        }
        if (itemClass.equals("WeaponHunting_Spear")) {
            val = 25;
        }
        if (itemClass.equals("WeaponMelee_Sword")) {
            val = 26;
        }
        if (itemClass.equals("WeaponArmor_Shield")) {
            val = 31;
        }
        if (itemClass.equals("WeaponArmor_Offhand")) {
            val = 32;
        }
        if (itemClass.equals("WeaponMelee_Axe2h")) {
            val = 41;
        }
        if (itemClass.equals("WeaponMelee_Mace2h")) {
            val = 42;
        }
        if (itemClass.equals("WeaponMelee_Spear2h")) {
            val = 43;
        }
        if (itemClass.equals("WeaponMagical_Staff")) {
            val = 44;
        }
        if (itemClass.equals("WeaponMelee_Sword2h")) {
            val = 45;
        }
        if (itemClass.equals("WeaponHunting_Ranged1h")) {
            val = 51;
        }
        if (itemClass.equals("WeaponHunting_Ranged2h")) {
            val = 52;
        }
        if (itemClass.equals("ItemArtifactFormula")) {
            val = 61;
        }
        return val;
    }

    private static List<ItemCount> getUniques() {
        final List<DBItem> list = DBItem.getAllUniques();
        final List<DBItem> bp = DBItem.getAllBlueprints();
        list.addAll(bp);
        return filterItems(list);
    }

    private static List<ItemCount> getGDStashItemListUniques(final List<GDItem> list) {
        if (list == null) {
            return null;
        }
        final List<GDItem> uniques = new LinkedList<GDItem>();
        for (final GDItem gdi : list) {
            if (gdi.isUnique()) {
                uniques.add(gdi);
            }
        }
        return buildItemCount(uniques);
    }

    private static List<ItemCount> getLegendaries() {
        final List<DBItem> list = DBItem.getAllLegendaries();
        final List<DBItem> bp = DBItem.getAllLegendaryBlueprints();
        list.addAll(bp);
        return filterItems(list);
    }

    private static List<ItemCount> getGDStashItemListLegendaries(final List<GDItem> list) {
        if (list == null) {
            return null;
        }
        final List<GDItem> legendaries = new LinkedList<GDItem>();
        for (final GDItem gdi : list) {
            if (gdi.isLegendary()) {
                legendaries.add(gdi);
            }
        }
        return buildItemCount(legendaries);
    }

    private static List<ItemCount> filterItems(final List<DBItem> list) {
        final List<ItemCount> allItems = new LinkedList<ItemCount>();
        if (list == null) {
            return allItems;
        }
        for (final DBItem dbi : list) {
            final String id = dbi.getItemID();
            final List<GDItem> items = DBStashItem.getGDItemsByItemID(id);
            final Iterator<GDItem> iterator2 = items.iterator();
            if (iterator2.hasNext()) {
                final GDItem gdi = iterator2.next();
                allItems.add(new ItemCount(gdi, items.size()));
            }
        }
        return allItems;
    }

    private static List<ItemCount> buildItemCount(final List<GDItem> list) {
        final List<ItemCount> allItems = new LinkedList<ItemCount>();
        if (list == null) {
            return allItems;
        }
        for (final GDItem gdi : list) {
            final String id = gdi.getItemID();
            boolean found = false;
            for (final ItemCount ic : allItems) {
                if (id.equals(ic.getItemID())) {
                    found = true;
                    ic.incrementCount();
                    break;
                }
            }
            if (!found) {
                allItems.add(new ItemCount(gdi));
            }
        }
        return allItems;
    }

    private static String buildText(final List<ItemCount> items) {
        Collections.<ItemCount>sort(items, new Sorter());
        String text = "";
        String rarity = null;
        String itemClass = null;
        final String set = null;
        boolean firstList = true;
        for (final ItemCount gdi : items) {
            final String iRare = gdi.getRarity();
            final String iClass = gdi.getItemClass();
            boolean newRarity = false;
            boolean newClass = false;
            boolean newList = false;
            newRarity = (rarity == null || !rarity.equals(iRare));
            newClass = (itemClass == null || !itemClass.equals(iClass));
            rarity = iRare;
            itemClass = iClass;
            String preList = "";
            if (newRarity) {
                String s = null;
                if (rarity.equals("Epic")) {
                    s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, "TXT_EPIC_ITEMS");
                    final Object[] args = {s};
                    s = GDMsgFormatter.format(GDMsgFormatter.rbHTML, "TAG_EPIC_HEADER", args);
                }
                if (rarity.equals("Legendary")) {
                    s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, "TXT_LEGENDARY_ITEMS");
                    final Object[] args = {s};
                    s = GDMsgFormatter.format(GDMsgFormatter.rbHTML, "TAG_LEGENDARY_HEADER", args);
                }
                if (s != null) {
                    preList = preList + s + GDConstants.LINE_SEPARATOR;
                }
                newList = true;
            }
            if (newClass) {
                String s = null;
                if (rarity.equals("Epic")) {
                    s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, itemClass);
                    final Object[] args = {s};
                    s = GDMsgFormatter.format(GDMsgFormatter.rbHTML, "TAG_EPIC_ITEMTYPE", args);
                }
                if (rarity.equals("Legendary")) {
                    s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, itemClass);
                    final Object[] args = {s};
                    s = GDMsgFormatter.format(GDMsgFormatter.rbHTML, "TAG_LEGENDARY_ITEMTYPE", args);
                }
                if (s != null) {
                    preList = preList + s + GDConstants.LINE_SEPARATOR;
                }
                newList = true;
            }
            if (newList) {
                if (firstList) {
                    firstList = false;
                } else {
                    final String s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, "TAG_LIST_END");
                    if (s != null) {
                        text = text + s + GDConstants.LINE_SEPARATOR;
                    }
                }
                if (preList.length() > 0) {
                    text += preList;
                }
                String s = null;
                s = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, "TAG_LIST_BEGIN");
                if (s != null) {
                    text = text + s + GDConstants.LINE_SEPARATOR;
                }
            }
            String s = gdi.getDescription();
            if (s != null) {
                text = text + s + GDConstants.LINE_SEPARATOR;
            }
        }
        if (!firstList) {
            final String s2 = GDMsgFormatter.getString(GDMsgFormatter.rbHTML, "TAG_LIST_END");
            if (s2 != null) {
                text = text + s2 + GDConstants.LINE_SEPARATOR;
            }
        }
        return text;
    }

    public static void extractUniques() {
        final List<ItemCount> items = getUniques();
        exportItems(items);
    }

    public static void extractUniques(final List<GDItem> list) {
        List<ItemCount> items = getGDStashItemListUniques(list);
        if (list == null || list.isEmpty()) {
            items = getUniques();
        }
        exportItems(items);
    }

    public static void extractLegendaries() {
        final List<ItemCount> items = getLegendaries();
        exportItems(items);
    }

    public static void extractLegendaries(final List<GDItem> list) {
        List<ItemCount> items = getGDStashItemListLegendaries(list);
        if (list == null || list.isEmpty()) {
            items = getLegendaries();
        }
        exportItems(items);
    }

    public static void exportItems(final List<ItemCount> items) {
        final String text = buildText(items);
        final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        final StringSelection strSel = new StringSelection(text);
        clipboard.setContents(strSel, null);
    }

    private static class Sorter implements Comparator<ItemCount> {
        @Override
        public int compare(final ItemCount i1, final ItemCount i2) {
            if (i1 == null) {
                if (i2 == null) {
                    return 0;
                }
                return -1;
            } else {
                if (i2 == null) {
                    return 1;
                }
                final int ir1 = getRarityInt(i1.getRarity());
                final int ir2 = getRarityInt(i2.getRarity());
                if (ir1 > ir2) {
                    return 1;
                }
                if (ir1 < ir2) {
                    return -1;
                }
                final int ic1 = getItemClassInt(i1.getItemClass());
                final int ic2 = getItemClassInt(i2.getItemClass());
                if (ic1 > ic2) {
                    return 1;
                }
                if (ic1 < ic2) {
                    return -1;
                }
                final String in1 = i1.getLongItemName();
                final String in2 = i2.getLongItemName();
                if (in1 == null) {
                    if (in2 == null) {
                        return 0;
                    }
                    return -1;
                } else {
                    if (in2 == null) {
                        return 1;
                    }
                    return in1.compareTo(in2);
                }
            }
        }
    }

    private static class ItemCount {
        private GDItem item;
        private int count;

        public ItemCount(final GDItem item) {
            this(item, 1);
        }

        public ItemCount(final GDItem item, final int count) {
            this.item = item;
            this.count = count;
            if (item.getStackCount() > 1) {
                this.count = item.getStackCount();
            }
        }

        public String getDescription() {
            String name = this.item.getLongItemName();
            if (this.item.getItemSetName() != null) {
                name = name + " [" + this.item.getItemSetName() + "]";
            }
            String tagItem = "TAG_LIST_ITEM";
            if (this.item.getRarity().equals("Epic")) {
                tagItem = "TAG_LIST_ITEM_EPIC";
            }
            if (this.item.getRarity().equals("Legendary")) {
                tagItem = "TAG_LIST_ITEM_LEGENDARY";
            }
            String text = null;
            if (this.count > 1) {
                tagItem += "_MULTI";
                final Object[] args = {name, this.count};
                text = GDMsgFormatter.format(GDMsgFormatter.rbHTML, tagItem, args);
            } else {
                final Object[] args = {name};
                text = GDMsgFormatter.format(GDMsgFormatter.rbHTML, tagItem, args);
            }
            return text;
        }

        public String getItemID() {
            return this.item.getItemID();
        }

        public void incrementCount() {
            ++this.count;
        }

        public String getRarity() {
            return this.item.getRarity();
        }

        public String getItemClass() {
            return this.item.getItemClass();
        }

        public String getLongItemName() {
            return this.item.getLongItemName();
        }
    }
}
